Skip to content

Conversation

@kazutakahirata
Copy link
Contributor

This patch removes DenseMap::init and SmallDenseMap::init by inlining
them into their call sites and simplifying them.

init() is defined as:

void init(unsigned InitNumEntries) {
auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
this->initWithExactBucketCount(InitBuckets);
}

  • Constuctors: Now that we have constructors that allocate the exact
    number of buckets (as opposed to the number of key/value pairs),
    init() does too much. Once we convert the number of key/value pairs
    to the number of buckets, we can call the constructors that take the
    exact number of buckets.

  • init(0) in the move assignment operators simplifies down to:

    initWithExactBucketCount(0)

  • shrink_and_clear() computes the number of buckets to have after the
    clear operation. As such, we should call initWithExactBucketCount,
    not init. Otherwise, we would end up adding "load factor padding"
    on top of NewNumBuckets:

    NextPowerOf2(NewNumBuckets * 4 / 3 + 1)

All in all, init() doesn't bring any value in the current setup.

This patch is part of the effort outlined in #168255.

This patch removes DenseMap::init and SmallDenseMap::init by inlining
them into their call sites and simplifying them.

init() is defined as:

  void init(unsigned InitNumEntries) {
    auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
    this->initWithExactBucketCount(InitBuckets);
  }

- Constuctors: Now that we have constructors that allocate the exact
  number of buckets (as opposed to the number of key/value pairs),
  init() does too much.  Once we convert the number of key/value pairs
  to the number of buckets, we can call the constructors that take the
  exact number of buckets.

- init(0) in the move assignment operators simplifies down to:

    initWithExactBucketCount(0)

- shrink_and_clear() computes the number of buckets to have after the
  clear operation.  As such, we should call initWithExactBucketCount,
  not init.  Otherwise, we would end up adding "load factor padding"
  on top of NewNumBuckets:

    NextPowerOf2(NewNumBuckets * 4 / 3 + 1)

All in all, init() doesn't bring any value in the current setup.

This patch is part of the effort outlined in llvm#168255.
@llvmbot
Copy link
Member

llvmbot commented Nov 17, 2025

@llvm/pr-subscribers-llvm-adt

Author: Kazu Hirata (kazutakahirata)

Changes

This patch removes DenseMap::init and SmallDenseMap::init by inlining
them into their call sites and simplifying them.

init() is defined as:

void init(unsigned InitNumEntries) {
auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
this->initWithExactBucketCount(InitBuckets);
}

  • Constuctors: Now that we have constructors that allocate the exact
    number of buckets (as opposed to the number of key/value pairs),
    init() does too much. Once we convert the number of key/value pairs
    to the number of buckets, we can call the constructors that take the
    exact number of buckets.

  • init(0) in the move assignment operators simplifies down to:

    initWithExactBucketCount(0)

  • shrink_and_clear() computes the number of buckets to have after the
    clear operation. As such, we should call initWithExactBucketCount,
    not init. Otherwise, we would end up adding "load factor padding"
    on top of NewNumBuckets:

    NextPowerOf2(NewNumBuckets * 4 / 3 + 1)

All in all, init() doesn't bring any value in the current setup.

This patch is part of the effort outlined in #168255.


Full diff: https://github.com/llvm/llvm-project/pull/168322.diff

1 Files Affected:

  • (modified) llvm/include/llvm/ADT/DenseMap.h (+10-19)
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index aa5d8a8729647..e6f4a4d4e676e 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -162,7 +162,7 @@ class DenseMapBase : public DebugEpochBase {
       return;
     }
     derived().deallocateBuckets();
-    derived().init(NewNumBuckets);
+    initWithExactBucketCount(NewNumBuckets);
   }
 
   /// Return true if the specified key is in the map, false otherwise.
@@ -750,9 +750,9 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
 public:
   /// Create a DenseMap with an optional \p NumElementsToReserve to guarantee
   /// that this number of elements can be inserted in the map without grow().
-  explicit DenseMap(unsigned NumElementsToReserve = 0) {
-    init(NumElementsToReserve);
-  }
+  explicit DenseMap(unsigned NumElementsToReserve = 0)
+      : DenseMap(BaseT::getMinBucketToReserveForEntries(NumElementsToReserve),
+                 typename BaseT::ExactBucketCount{}) {}
 
   DenseMap(const DenseMap &other) : DenseMap() { this->copyFrom(other); }
 
@@ -784,7 +784,7 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
   DenseMap &operator=(DenseMap &&other) {
     this->destroyAll();
     deallocateBuckets();
-    init(0);
+    this->initWithExactBucketCount(0);
     this->swap(other);
     return *this;
   }
@@ -825,11 +825,6 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
     return true;
   }
 
-  void init(unsigned InitNumEntries) {
-    auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
-    this->initWithExactBucketCount(InitBuckets);
-  }
-
   // Put the zombie instance in a known good state after a move.
   void kill() {
     deallocateBuckets();
@@ -898,9 +893,10 @@ class SmallDenseMap
   }
 
 public:
-  explicit SmallDenseMap(unsigned NumElementsToReserve = 0) {
-    init(NumElementsToReserve);
-  }
+  explicit SmallDenseMap(unsigned NumElementsToReserve = 0)
+      : SmallDenseMap(
+            BaseT::getMinBucketToReserveForEntries(NumElementsToReserve),
+            typename BaseT::ExactBucketCount{}) {}
 
   SmallDenseMap(const SmallDenseMap &other) : SmallDenseMap() {
     this->copyFrom(other);
@@ -935,7 +931,7 @@ class SmallDenseMap
   SmallDenseMap &operator=(SmallDenseMap &&other) {
     this->destroyAll();
     deallocateBuckets();
-    init(0);
+    this->initWithExactBucketCount(0);
     this->swap(other);
     return *this;
   }
@@ -1091,11 +1087,6 @@ class SmallDenseMap
     return true;
   }
 
-  void init(unsigned InitNumEntries) {
-    auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
-    this->initWithExactBucketCount(InitBuckets);
-  }
-
   // Put the zombie instance in a known good state after a move.
   void kill() {
     deallocateBuckets();

@kazutakahirata kazutakahirata merged commit 3c54972 into llvm:main Nov 17, 2025
12 checks passed
@kazutakahirata kazutakahirata deleted the cleanup_20251116e_ADT_DenseMap_init branch November 17, 2025 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants